source("calc_footprint_FFP.R")
library(ggplot2)
library(modelr)
options(na.action = na.warn)

Lists

rm(list=ls())

Defining the data I/O directory for the Eddy Master File

**

path_eddy<-"C:\\Users\\Tommy\\flux\\Data-exploring\\02_Concord\\"
path.in_eddy<-paste(path_eddy,"01_Proccessed_Data",sep="")
path.out_eddy<-paste(path_eddy,"03_combined_data",sep="")
ver<-"Master_Eddy" 
file.name_eddy<-paste("master_eddy_pro_concord",sep="")

read in eddypro full output Master file, parse variable names

data_master_eddy<-read.csv(paste(path.in_eddy,"\\",ver,"\\",file.name_eddy,".csv",sep=""),
                  header=F,
                  skip=3,
                  na.strings=c(-9999),
                  stringsAsFactors = F)
colnames(data_master_eddy)<-colnames(
  read.csv(paste(path.in_eddy,"\\",ver,"\\",file.name_eddy,".csv",sep=""),
           header=T,
           skip=1))

data_master_eddy

Defining the data I/O directory for the Master met_data

path_met<-"C:\\Users\\Tommy\\flux\\Data-exploring\\02_Concord\\"
path.in_met<-paste(path_met,"01_Proccessed_Data",sep="")
path.out_met<-paste(path_met,"03_combined_data",sep="")
ver<-"met_data" 
file.name<-paste("MET_data_master",sep="")

#read in Met_Data Master file, parse variable names and define N/As#

met_data_master<-read.csv(paste(path.in_met,"\\",ver,"\\",file.name,".csv",sep=""),
                  header=F,
                  skip=4,
                  na.strings=c("NAN"),
                  stringsAsFactors = F)
colnames(met_data_master)<-colnames(
  read.csv(paste(path.in_met,"\\",ver,"\\",file.name,".csv",sep=""),
           header=T,
           skip= 1))

met_data_master
NA

Parsing the time stamp converting it into a POSIXlt vector

interpreting date and time into new timestamp column

Then taking that time stamp column and turning each time into a unique number (time.id) so I can join based on that. As it can be really tricky to join/merge based on time stamps alone

Or I could make sure both time stamps are characters and match them that way

Finally ploting time.id to make sure my times translate linearily

data_master_eddy$TIMESTAMP<-strptime(paste(data_master_eddy$date,data_master_eddy$time,sep=" "),format="%m/%d/%Y %H:%M", tz = "GMT")

data_master_eddy$time.id<-data_master_eddy$TIMESTAMP$year+1900+(data_master_eddy$TIMESTAMP$yday)/366+(data_master_eddy$TIMESTAMP$hour)/366/24+ (data_master_eddy$TIMESTAMP$min)/366/24/60

data_master_eddy$time.id[1:50]
 [1] 2019.450 2019.450 2019.450 2019.450 2019.450 2019.450 2019.450 2019.450 2019.451
[10] 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451
[19] 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451 2019.451 2019.452 2019.452
[28] 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452
[37] 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452 2019.452 2019.453 2019.453
[46] 2019.453 2019.453 2019.453 2019.453 2019.453
plot(data_master_eddy$time.id)

which(duplicated(data_master_eddy$time.id))
integer(0)

#Taking the met_data and turning the time stamp into posixt format#

met_data_master$TIMESTAMP<-strptime(met_data_master$TIMESTAMP,
                           format ="%m/%d/%Y %H:%M", tz = "GMT")

met_data_master$TIMESTAMP[1:20]
 [1] "2019-06-25 09:00:00 GMT" "2019-06-25 09:30:00 GMT" "2019-06-25 10:00:00 GMT"
 [4] "2019-06-25 10:30:00 GMT" "2019-06-25 11:00:00 GMT" "2019-06-25 11:30:00 GMT"
 [7] "2019-06-25 12:00:00 GMT" "2019-06-25 12:30:00 GMT" "2019-06-25 13:00:00 GMT"
[10] "2019-06-25 13:30:00 GMT" "2019-06-25 14:00:00 GMT" "2019-06-25 14:30:00 GMT"
[13] "2019-06-25 15:00:00 GMT" "2019-06-25 15:30:00 GMT" "2019-06-25 16:00:00 GMT"
[16] "2019-06-25 16:30:00 GMT" "2019-06-25 17:00:00 GMT" "2019-06-25 17:30:00 GMT"
[19] "2019-06-25 18:00:00 GMT" "2019-06-25 18:30:00 GMT"

#Making sure timestamp columns line up#


met_data_master$TIMESTAMP[1:10]
 [1] "2019-06-25 09:00:00 GMT" "2019-06-25 09:30:00 GMT" "2019-06-25 10:00:00 GMT"
 [4] "2019-06-25 10:30:00 GMT" "2019-06-25 11:00:00 GMT" "2019-06-25 11:30:00 GMT"
 [7] "2019-06-25 12:00:00 GMT" "2019-06-25 12:30:00 GMT" "2019-06-25 13:00:00 GMT"
[10] "2019-06-25 13:30:00 GMT"
data_master_eddy$TIMESTAMP[1:10]
 [1] "2019-06-14 17:30:00 GMT" "2019-06-14 18:00:00 GMT" "2019-06-14 18:30:00 GMT"
 [4] "2019-06-14 19:00:00 GMT" "2019-06-14 19:30:00 GMT" "2019-06-14 20:00:00 GMT"
 [7] "2019-06-14 20:30:00 GMT" "2019-06-14 21:00:00 GMT" "2019-06-14 21:30:00 GMT"
[10] "2019-06-14 22:00:00 GMT"
met_data_master

#creating a time id for the MET Data so I I can join the MET and Eddy Pro Data#


met_data_master$time.id <-met_data_master$TIMESTAMP$year+1900+(met_data_master$TIMESTAMP$yday)/366+(met_data_master$TIMESTAMP$hour)/366/24 + (met_data_master$TIMESTAMP$min)/366/24/60 

met_data_master$time.id[1:20]
 [1] 2019.479 2019.479 2019.479 2019.479 2019.479 2019.479 2019.480 2019.480 2019.480
[10] 2019.480 2019.480 2019.480 2019.480 2019.480 2019.480 2019.480 2019.480 2019.480
[19] 2019.480 2019.480
plot(met_data_master$time.id)

which(duplicated(met_data_master$time.id))
integer(0)
met_data_master

#Joining the Met_Data and Eddy Pro Data Sets#

with merge


combo_master_ed_met<- merge(met_data_master[,-which(colnames(met_data_master)=="TIMESTAMP")], data_master_eddy[,-which(colnames(data_master_eddy)=="TIMESTAMP")], by = "time.id")

combo_master_ed_met

colnames(combo_master_ed_met)
  [1] "time.id"                       "RECORD"                       
  [3] "BattV_Avg"                     "PTemp_C_Avg"                  
  [5] "AM25T_ref_Avg"                 "TC_Avg.1."                    
  [7] "TC_Avg.2."                     "TC_Avg.3."                    
  [9] "TC_Avg.4."                     "TC_Avg.5."                    
 [11] "TC_Avg.6."                     "TC_Avg.7."                    
 [13] "TC_Avg.8."                     "TC_Avg.9."                    
 [15] "TC_Avg.10."                    "TC_Avg.11."                   
 [17] "TC_Avg.12."                    "TC_Avg.13."                   
 [19] "TC_Avg.14."                    "TC_Avg.15."                   
 [21] "TC_Avg.16."                    "TC_Avg.17."                   
 [23] "TC_Avg.18."                    "TC_Avg.19."                   
 [25] "TC_Avg.20."                    "TC_Avg.21."                   
 [27] "TC_Avg.22."                    "TC_Avg.23."                   
 [29] "TC_Avg.24."                    "TC_Avg.25."                   
 [31] "AirT_Avg"                      "RH_Avg"                       
 [33] "AtmPressure_Avg"               "NR_mV_Avg"                    
 [35] "NR_Wm2_Avg"                    "PAR_in_mV_Avg"                
 [37] "PAR_in_uEm2_Avg"               "PAR_out_mV_Avg"               
 [39] "PAR_out_uEm2_Avg"              "SHF_1_mV_Avg"                 
 [41] "SHF_1_Wm2_Avg"                 "SHF_2_mV_Avg"                 
 [43] "SHF_2_Wm2_Avg"                 "WaterP_Avg"                   
 [45] "WaterT_Avg"                    "Precip_mm_Tot"                
 [47] "VWC_Avg"                       "EC_Avg"                       
 [49] "T_Avg"                         "P_Avg"                        
 [51] "PA_Avg"                        "VR_Avg"                       
 [53] "filename"                      "date"                         
 [55] "time"                          "DOY"                          
 [57] "daytime"                       "file_records"                 
 [59] "used_records"                  "Tau"                          
 [61] "qc_Tau"                        "H"                            
 [63] "qc_H"                          "LE"                           
 [65] "qc_LE"                         "co2_flux"                     
 [67] "qc_co2_flux"                   "h2o_flux"                     
 [69] "qc_h2o_flux"                   "H_strg"                       
 [71] "LE_strg"                       "co2_strg"                     
 [73] "h2o_strg"                      "co2_v.adv"                    
 [75] "h2o_v.adv"                     "co2_molar_density"            
 [77] "co2_mole_fraction"             "co2_mixing_ratio"             
 [79] "co2_time_lag"                  "co2_def_timelag"              
 [81] "h2o_molar_density"             "h2o_mole_fraction"            
 [83] "h2o_mixing_ratio"              "h2o_time_lag"                 
 [85] "h2o_def_timelag"               "sonic_temperature"            
 [87] "air_temperature"               "air_pressure"                 
 [89] "air_density"                   "air_heat_capacity"            
 [91] "air_molar_volume"              "ET"                           
 [93] "water_vapor_density"           "e"                            
 [95] "es"                            "specific_humidity"            
 [97] "RH"                            "VPD"                          
 [99] "Tdew"                          "u_unrot"                      
[101] "v_unrot"                       "w_unrot"                      
[103] "u_rot"                         "v_rot"                        
[105] "w_rot"                         "wind_speed"                   
[107] "max_wind_speed"                "wind_dir"                     
[109] "yaw"                           "pitch"                        
[111] "roll"                          "u."                           
[113] "TKE"                           "L"                            
[115] "X.z.d..L"                      "bowen_ratio"                  
[117] "T."                            "model"                        
[119] "x_peak"                        "x_offset"                     
[121] "x_10."                         "x_30."                        
[123] "x_50."                         "x_70."                        
[125] "x_90."                         "un_Tau"                       
[127] "Tau_scf"                       "un_H"                         
[129] "H_scf"                         "un_LE"                        
[131] "LE_scf"                        "un_co2_flux"                  
[133] "co2_scf"                       "un_h2o_flux"                  
[135] "h2o_scf"                       "spikes_hf"                    
[137] "amplitude_resolution_hf"       "drop_out_hf"                  
[139] "absolute_limits_hf"            "skewness_kurtosis_hf"         
[141] "skewness_kurtosis_sf"          "discontinuities_hf"           
[143] "discontinuities_sf"            "timelag_hf"                   
[145] "timelag_sf"                    "attack_angle_hf"              
[147] "non_steady_wind_hf"            "u_spikes"                     
[149] "v_spikes"                      "w_spikes"                     
[151] "ts_spikes"                     "co2_spikes"                   
[153] "h2o_spikes"                    "chopper_LI.7500"              
[155] "detector_LI.7500"              "pll_LI.7500"                  
[157] "sync_LI.7500"                  "mean_value_RSSI_LI.7500"      
[159] "u_var"                         "v_var"                        
[161] "w_var"                         "ts_var"                       
[163] "co2_var"                       "h2o_var"                      
[165] "w.ts_cov"                      "w.co2_cov"                    
[167] "w.h2o_cov"                     "vin_sf_mean"                  
[169] "co2_mean"                      "h2o_mean"                     
[171] "dew_point_mean"                "co2_signal_strength_7500_mean"

#Add back time stamp to the combo_master_ed_met#

combo_master_ed_met$TIMESTAMP<-strptime(paste(combo_master_ed_met$date,combo_master_ed_met$time,sep=" "),format="%m/%d/%Y %H:%M", tz = "GMT")

combo_master_ed_met$TIMESTAMP[1:10]
 [1] "2019-06-25 09:00:00 GMT" "2019-06-25 09:30:00 GMT" "2019-06-25 10:00:00 GMT"
 [4] "2019-06-25 10:30:00 GMT" "2019-06-25 11:00:00 GMT" "2019-06-25 11:30:00 GMT"
 [7] "2019-06-25 12:00:00 GMT" "2019-06-25 12:30:00 GMT" "2019-06-25 13:00:00 GMT"
[10] "2019-06-25 13:30:00 GMT"
combo_master_ed_met$TIMESTAMP[10451:10453]
[1] "2020-02-05 08:00:00 GMT" "2020-02-05 08:30:00 GMT" "2020-02-05 09:30:00 GMT"
combo_master_ed_met
NA
NA
NA

#Creating a CSV File of my combined Master File!#

write.csv(combo_master_ed_met,
          paste(path.out_eddy,ver,"combo_master_ed_met",sep=""),
          quote = T,
          row.names = F)

#filtering data for quality control filters# filtering latent heat, sensible heat, co2 flux, qc_tau and h20flux by quality controls

combo_master_ed_met$LE.[!is.na(combo_master_ed_met$qc_LE)&combo_master_ed_met$qc_LE==2]<-NA

combo_master_ed_met$qqc_h2o_flux[!is.na(combo_master_ed_met$qc_h2o_flux)&combo_master_ed_met$qc_h2o_flux==2]<-NA

combo_master_ed_met$H[!is.na(combo_master_ed_met$qc_H)&combo_master_ed_met$qc_H==2]<-NA

combo_master_ed_met$u.[!is.na(combo_master_ed_met$qc_Tau)&combo_master_ed_met$qc_Tau==2]<-NA

combo_master_ed_met$co2_flux[!is.na(combo_master_ed_met$co2_flux)&combo_master_ed_met$co2_flux==2]<-NA

latent heat, sensible heat, h20_flux, and relative humidity by day for whole period


plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$LE)

hist(combo_master_ed_met$LE)


plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$h2o_flux)


plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$H)


plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$RH)

NA
NA
NA
NA
NA
NA

#Half Hour Flux Averages

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$co2_flux,xlab='Time', ylab='Co2 Fluxes', main=' Half Hour Co2 Flux Averages',  ylim = c(-20,20),pch=1,col="blue",cex=0.4)

#Daily average of fluxes


plot(tapply(combo_master_ed_met$co2_flux ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)), xlab='Time', ylab='Co2 Fluxes', main='Daily Co2 Flux Averages',pch=1,col="red",cex=1.5)

#Plotting Co2 flux by timstamp on x-axis. First half-hourly data and daily data stacked

layout(matrix(c(1,1,2,2), 2, 2, byrow = TRUE))
plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$co2_flux, xlab='Time', ylab='Co2 Fluxes', main='Half Hour Flux Averages',  ylim = c(-15,15),pch=1,col="blue",cex=0.4)
plot(tapply(combo_master_ed_met$co2_flux ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)), xlab='Time', ylab='Co2 Fluxes', main='Daily Co2 Flux Averages',pch=1,col="red",cex=1.5)

NA
NA

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$co2_flux,
  ylim = c(-10, 10),
               cex=0.6,col="grey",
               xlab= 'Time', 
               ylab="", 
               main='',las=1,
               lpars=list(lwd=3,col="red"))
mtext(side=2,expression(CO[2]~Flux~'('~mu~mol~m^{-2}~s^{-1}~')'),line=2.5)
par(new= TRUE)
plot(tapply(combo_master_ed_met$co2_flux ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),
     xaxt='n', 
     xlab='Time', 
     ylab='', 
     main='', las =1,
     ylim = c(-10,10),
     lty=1,col="red",
     lwd=2,type="l")
mtext(side=2,expression(CO[2]~Flux~'('~mu~mol~m^{-2}~s^{-1}~')'),line=2.5)
abline(h=0,col="black")

#Plotting daily flux average over half hour fluxes



plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$co2_flux, 
     xlab='Time', 
     ylab='Co2 Fluxes', 
     main='',  ylim = c(-10,10),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$co2_flux ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Co2 Fluxes', main='',ylim = c(-10,10),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")
legend(x='bottomright',legend=c('1/2 hour fluxes', 'daily flux averages'),
col=c('grey', 'red'), pch=c(1,19))

#Daily average of Sensible Heat

plot(tapply(combo_master_ed_met$H,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xlab='Time', ylab='Sensible Heat', main='Daily Average of Sensible Heat')

#Daily average of Latent Heat

plot(tapply(combo_master_ed_met$LE ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xlab='Time', ylab='Latent Heat', main='Daily Average of Latent Heat')

#line plot of c02_fluxes#

ggplot(data = combo_master_ed_met) + 
  geom_line(mapping = aes(x = time.id , y = co2_flux)) 

#latent heat and Sensible heat plotted over eachother

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$LE,
     xlab='Time', 
     ylab='Latent and Sensible Heat', 
     main='Latent and Sensible Heat',pch=1,col="blue",cex=0.6)
points(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$H,
       col="red",
       pch=1,
       cex=0.6)
legend(x='bottomright',legend=c('Latent Heat', 'Sensible Heat'),
col=c('blue', 'red'), pch=c(1,19))

#air temperatue by sensible heat an U* by co2 flux

plot(combo_master_ed_met$air_temperature-273.15,combo_master_ed_met$H,xlim=c(10,40),ylim=c(-100,500))




plot(combo_master_ed_met$u. ,combo_master_ed_met$co2_flux, ylim = c(0, 10), xlim = c(0,1))

#Adding best fit line to air temperature by sensible heat

ggplot(data = combo_master_ed_met) + 
  geom_point(mapping = aes(x = air_temperature-273.15, y = H)) +
  geom_smooth(mapping = aes(x = air_temperature-273.15, y = H))

NA
NA

#best fit line to U* bt co2 flux

ggplot(data = combo_master_ed_met) + 
  geom_point(mapping = aes(x = u., y = co2_flux)) +
  geom_smooth(mapping = aes(x = u., y = co2_flux))

NA
NA

hist(combo_master_ed_met$wind_dir, xlim = c(0,370), breaks = 36, main = "Wind Direction at Concord Tower", xlab = 'Degrees')

#Comparing MET Temperature data to temperature reading from Licor intruments#

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$PTemp_C_Avg)
points(combo_master_ed_met$TIMESTAMP,combo_master_ed_met$air_temperature-273.15,col="red",pch=2)

#Adding coefficient to Net radiation#

combo_master_ed_met$Correct_NR = (combo_master_ed_met$NR_Wm2_Avg*10)/14.2

#plotting air temperature from data logger. see where our gaps line up. lines up with net radiation and gaps

plot(combo_master_ed_met$AirT_Avg)

#plotting Net Radation to see the bad data.

summary(combo_master_ed_met$Correct_NR[c(1:600,2500:4000)])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-106.27  -69.79  -17.23  121.53  339.30  644.37 
plot(combo_master_ed_met$Correct_NR)

#filtering out bad NR numbers


combo_master_ed_met$Correct_NR[!is.na(combo_master_ed_met$Correct_NR)&(combo_master_ed_met$Correct_NR<(-150)|combo_master_ed_met$Correct_NR>800)]<-NA
summary(combo_master_ed_met$Correct_NR)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
-146.97  -60.91  -37.46   56.03  135.53  775.35    3581 
plot(combo_master_ed_met$Correct_NR)

summary(combo_master_ed_met$Correct_NR)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
-146.97  -60.91  -37.46   56.03  135.53  775.35    3581 

#Adding coefficient to Soil Heat Flux Data

plot(combo_master_ed_met$SHF_1_mV_Avg,ylim=c(-10,10))

combo_master_ed_met$Correct_shf_1 = (combo_master_ed_met$SHF_1_mV_Avg*16.455)
plot(combo_master_ed_met$Correct_shf_1,ylim=c(-50,50))

#plotting Soil heat flux to see the bad data.


summary(combo_master_ed_met$Correct_shf_1)
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max.      NA's 
-3118.222   -15.270    -6.335   -38.461    10.910  1507.278      2459 
summary(combo_master_ed_met$Correct_shf_1[c(2500:4000)])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-14.349  -8.919  -3.538   1.246  10.877  33.206 
plot(combo_master_ed_met$Correct_shf_1)

plot(combo_master_ed_met$Correct_shf_1[c(2500:4000)], ylim = c(-50,50),xlab='8/14/2019 to 02/05/2020', ylab='Soil Heat Flux_1 ', main='Half Hour Averages of Soil Heat Flux of the Concord Site')

#filtering out bad soil heat flux numbers


combo_master_ed_met$Correct_shf_1[!is.na(combo_master_ed_met$Correct_shf_1)&(combo_master_ed_met$Correct_shf_1<(-20)|combo_master_ed_met$Correct_shf_1>50)]<-NA
summary(combo_master_ed_met$Correct_shf_1)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
-19.993 -10.251  -4.542  -0.397   7.791  49.661    5208 
plot(combo_master_ed_met$Correct_shf_1)

Energy Balance of non-gapfilled data. Slope of line is energy balance closure. Ideally it should be 1:1 Net radiation - soil heat flux= to Latent heat +sensible heat.



combo_master_ed_met$E_ng = (combo_master_ed_met$Correct_NR-combo_master_ed_met$Correct_shf_1)

summary(combo_master_ed_met$E_ng )
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
-138.33  -52.06  -22.43   58.95  144.07  763.13    5295 
plot(combo_master_ed_met$E_ng)


combo_master_ed_met$E_le_and_H =(combo_master_ed_met$LE+combo_master_ed_met$H)
summary(combo_master_ed_met$E_le_and_H  )
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max.      NA's 
-514.8600  -18.4604    0.0379   58.3382  124.1671  810.8680      1634 
plot(combo_master_ed_met$E_le_and_H )


scatter.smooth(combo_master_ed_met$E_ng, combo_master_ed_met$E_le_and_H )

lm(combo_master_ed_met$E_le_and_H  ~ combo_master_ed_met$E_ng)
Dropping 6045 rows with missing values

Call:
lm(formula = combo_master_ed_met$E_le_and_H ~ combo_master_ed_met$E_ng)

Coefficients:
             (Intercept)  combo_master_ed_met$E_ng  
                 14.4377                    0.5487  
summary(lm(combo_master_ed_met$E_le_and_H  ~ combo_master_ed_met$E_ng-1))
Dropping 6045 rows with missing values

Call:
lm(formula = combo_master_ed_met$E_le_and_H ~ combo_master_ed_met$E_ng - 
    1)

Residuals:
    Min      1Q  Median      3Q     Max 
-460.58   -2.74   12.46   28.97  388.85 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)    
combo_master_ed_met$E_ng 0.578665   0.003364     172   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 46.69 on 5814 degrees of freedom
  (6045 observations deleted due to missingness)
Multiple R-squared:  0.8358,    Adjusted R-squared:  0.8357 
F-statistic: 2.958e+04 on 1 and 5814 DF,  p-value: < 2.2e-16

#1/2 hour and daily averages of Latent Heat

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$LE, 
     xlab='Time', 
     ylab= expression(Latent~Heat~'('~W~m^{-2}~')'), 
     main='',  
     ylim = c(-40,300),
     pch=1,
     col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$LE ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),
     xaxt='n', 
     xlab='Time', 
    ylab= expression(Latent~Heat~'('~W~m^{-2}~')'),  
     main='',
     ylim = c(-40,300),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$LE,
  ylim = c(-40, 300),
               cex=0.4,col="grey",
               xlab= 'Time', 
               ylab="", 
               main='',las=1,
               lpars=list(lwd=3,col="red"))
mtext(side=2,expression(Latent~Heat~'('~W~m^{-2}~')'),line=2.5)
par(new= TRUE)
plot(tapply(combo_master_ed_met$LE ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),
     xaxt='n', 
     xlab='Time', 
     ylab='', 
     main='', las =1,
     ylim = c(-40,300),
     col="red",pch=1,cex=1.0)
mtext(side=2,expression(Latent~Heat~'('~W~m^{-2}~')'),line=2.5)
abline(h=0,col="black")
legend(x='topright',legend=c('1/2 hour averages', 'daily averages'),
col=c('grey', 'red'), pch=c(19,1))

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$LE, 
     xlab='Time', 
     ylab='Latent Heat', 
     main='Latent Heat: Daily and Half Hour Averages', 
     ylim = c(-40,300),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$LE ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n'
     , xlab='Time',
     ylab='Latent Heat', 
     main='Latent Heat: Daily and Half Hour Averages',
     ylim = c(-40,300),
     col="red",pch=1,cex=1.0)
abline(h=0,col="black")
legend(x='topright',legend=c('1/2 hour averages', 'daily averages'),
col=c('grey', 'red'), pch=c(1,1))

#1/2 hour and daily averages of Sensible Heat

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$H, xlab='Time', ylab='Sensible Heat', main='Sensible Heat: Daily and Half Hour Averages',  ylim = c(-40,300),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$H ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Sensible Heat', main='Sensible Heat: Daily and Half Hour Averages',ylim = c(-40,300),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$H, xlab='Time', ylab='Sensible Heat', main='Sensible Heat: Daily and Half Hour Averages',  ylim = c(-40,300),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$H ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Sensible Heat', main='Sensible Heat: Daily and Half Hour Averages',ylim = c(-40,300),col="red",pch=1,cex=1.0)
abline(h=0,col="black")

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$H,
  ylim = c(-40, 300),
               cex=0.4,col="grey",
               xlab= 'Time', 
               ylab="", 
               main='',las=1,
               lpars=list(lwd=3,col="red"))
mtext(side=2,expression(Sensible~Heat~'('~W~m^{-2}~')'),line=2.5)
par(new= TRUE)
plot(tapply(combo_master_ed_met$H ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),
     xaxt='n', 
     xlab='Time', 
     ylab='', 
     main='', las =1,
     ylim = c(-40,300),
     col="red",pch=1,cex=1.0)
mtext(side=2,expression(Sensible~Heat~'('~W~m^{-2}~')'),line=2.5)
abline(h=0,col="black")

#Net Radiation Daily and 1/2 hour averages

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$Correct_NR, xlab='Time', ylab='Net Radiation', main='Net Radiation: Daily and Half Hour Averages',  ylim = c(-80,800),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$Correct_NR ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Net Radiation', main='Net Radiation: Daily and Half Hour Averages',ylim = c(-80,800),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")


plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$Correct_NR, xlab='Time', ylab='Net Radiation', main='Net Radiation: Daily and Half Hour Averages',  ylim = c(-80,800),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$Correct_NR ,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Net Radiation', main='Net Radiation: Daily and Half Hour Averages',ylim = c(-80,800),col="red",pch=1,cex=1.0)
abline(h=0,col="black")

#soil heat flux

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$Correct_shf_1, xlab='Time', ylab='Soil Heat Flux 1', main='Soil Heat Flux 1: Daily and Half Hour Averages',  ylim = c(-20,40),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$Correct_shf_1,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Soil Heat Flux 1', main='Soil Heat Flux 1: Daily and Half Hour Averages',ylim = c(-20,40),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$Correct_shf_1, xlab='Time', ylab='Soil Heat Flux', main='Soil Heat Flux 1: Daily and Half Hour Averages',  ylim = c(-20,40),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$Correct_shf_1,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Soil Heat Flux 1', main='Soil Heat Flux 1: Daily and Half Hour Averages',ylim = c(-20,40),col="red",pch=1,cex=1.0)
abline(h=0,col="black")

#air temperature daily and 1/2 hour averages

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$air_temperature-273.15, xlab='Time', ylab='Air Temperature C: Daily and 1/2 Hour Averages', main=' ',  ylim = c(5,40),pch=1,col="grey",cex=0.4)
par(new= TRUE)
plot(tapply(combo_master_ed_met$air_temperature-273.15,round(combo_master_ed_met$DOY),function(x) mean(x,na.rm=T)),xaxt='n', xlab='Time', ylab='Air Temperature C: Daily and 1/2 Hour Averages', main='',ylim = c(5,40),lty=1,col="red",lwd=2,type="l")
abline(h=0,col="black")

#Water Fluxes daily and 1/2 hour averages. cumulative water and co2

plot(combo_master_ed_met$TIMESTAMP ,combo_master_ed_met$h2o_flux, xlab='Time', ylab='H2O Fluxes', main='H2O Fluxes: Daily and Half Hour Averages',  ylim = c(-2,5),pch=1,col="grey",cex=0.4)
par(new= TRUE)

plot(tapply(combo_master_ed_met$h2o_flux,
            round(combo_master_ed_met$DOY),
            function(x) mean(x,na.rm=T)),
     xaxt='n',
     xlab='Time',
     ylab='H2O Fluxes',
     main='H2O Fluxes: Daily and Half Hour Averages',
     ylim = c(-2,5),
     lty=1,
     col="red",
     lwd=2,
     type="l")
abline(h=0,col="black")


plot(cumsum(tapply(combo_master_ed_met$h2o_flux,
            round(combo_master_ed_met$DOY),
            function(x) mean(x,na.rm=T)))*18.02/1000000*1800*48,
     xaxt='n',
     xlab='Days since June 25',
     ylab=expression(Cumulative~Evapotranspiration~'('~mm~')'),
     main='',
     ylim = c(0,240),
     lty=1,
     col="red",
     lwd=2,
     type="l")
axis(side=1,at=seq(0,240,by=30))


plot(cumsum(tapply(combo_master_ed_met$co2_flux,
            round(combo_master_ed_met$DOY),
            function(x) mean(x,na.rm=T)))*12/1000000*1800*48,
     xaxt='n',
     xlab='Days since June 25',
     ylab=expression(Cumulative~NEE~'('~g~C~m^{-2}~')'),
     main='',
     ylim = c(-100,100),
     lty=1,
     col="red",
     lwd=2,
     type="l")
axis(side=1,at=seq(0,240,by=30))

#Co2 fluxes v.s u star, temperature, and VPD


plot(combo_master_ed_met$u. ,combo_master_ed_met$co2_flux, ylim = c(-5, 10), xlim = c(0,1), xlab='U*', ylab='Co2 Fluxes', main='Co2 Fluxes v.s U*')


plot(combo_master_ed_met$VPD ,combo_master_ed_met$co2_flux, ylim = c(-5, 10), xlab='VPD', ylab='Co2 Fluxes', main='Co2 Fluxes v.s VPD*')


plot(combo_master_ed_met$air_temperature-273.15 ,combo_master_ed_met$co2_flux, ylim = c(-5, 10), xlab='Air Temperature (C)', ylab='Co2 Fluxes', main='Co2 Fluxes v.s Air temperature*')


plot(combo_master_ed_met$Correct_NR[combo_master_ed_met$daytime==1] ,combo_master_ed_met$co2_flux[combo_master_ed_met$daytime==1], ylim = c(-10, 10), xlab='Net Radiation', ylab='Co2 Fluxes', main='Co2 Fluxes v.s Net Radiation')


summary(combo_master_ed_met$VPD)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    0.0   217.0   565.6   890.6  1278.5  5784.0     540 
scatter.smooth(combo_master_ed_met$Correct_NR[combo_master_ed_met$daytime==1],
               combo_master_ed_met$co2_flux[combo_master_ed_met$daytime==1],
               ylim = c(-10, 10),
               cex=0.6,col="grey",
               xlab=expression(Daytime~Net~Radiation~'('~W~m^{-2}~')'), 
               ylab="", 
               main='',las=1,
               lpars=list(lwd=3,col="red"))
mtext(side=2,expression(CO[2]~Flux~'('~mu~mol~m^{-2}~s^{-1}~')'),line=2.5)


scatter.smooth(combo_master_ed_met$air_temperature[combo_master_ed_met$daytime==0&
                                                     combo_master_ed_met$u.>=0.15]-273.15,
               combo_master_ed_met$co2_flux[combo_master_ed_met$daytime==0&
                                                     combo_master_ed_met$u.>=0.15],
               ylim = c(-5, 10),
               cex=0.6,col="grey",
               xlab=expression(Air~Temperature~'('~degree~C~')'), 
               ylab="", 
               main='',las=1,
               lpars=list(lwd=3,col="red"))
mtext(side=2,expression(CO[2]~Flux~'('~mu~mol~m^{-2}~s^{-1}~')'),line=2.5)

#cumulative

LS0tDQp0aXRsZTogJ01ldF9NYXN0ZXIgTWVyZ2Ugd2l0aCBFZGR5X1Byb19NYXN0ZXI6IERhdGEgZnJvbSAyMDIwLTAxLTIwJw0Kb3V0cHV0Og0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQoNCg0KYGBge3J9DQoNCnNvdXJjZSgiY2FsY19mb290cHJpbnRfRkZQLlIiKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShtb2RlbHIpDQpvcHRpb25zKG5hLmFjdGlvbiA9IG5hLndhcm4pDQpgYGANCg0KDQojIExpc3RzICMNCmBgYHtyfQ0Kcm0obGlzdD1scygpKQ0KYGBgDQoNCiMgRGVmaW5pbmcgdGhlIGRhdGEgSS9PIGRpcmVjdG9yeSBmb3IgdGhlIEVkZHkgTWFzdGVyIEZpbGUgIw0KKioNCmBgYHtyfQ0KcGF0aF9lZGR5PC0iQzpcXFVzZXJzXFxUb21teVxcZmx1eFxcRGF0YS1leHBsb3JpbmdcXDAyX0NvbmNvcmRcXCINCnBhdGguaW5fZWRkeTwtcGFzdGUocGF0aF9lZGR5LCIwMV9Qcm9jY2Vzc2VkX0RhdGEiLHNlcD0iIikNCnBhdGgub3V0X2VkZHk8LXBhc3RlKHBhdGhfZWRkeSwiMDNfY29tYmluZWRfZGF0YSIsc2VwPSIiKQ0KdmVyPC0iTWFzdGVyX0VkZHkiIA0KZmlsZS5uYW1lX2VkZHk8LXBhc3RlKCJtYXN0ZXJfZWRkeV9wcm9fY29uY29yZCIsc2VwPSIiKQ0KYGBgDQoNCiMgcmVhZCBpbiBlZGR5cHJvIGZ1bGwgb3V0cHV0IE1hc3RlciBmaWxlLCBwYXJzZSB2YXJpYWJsZSBuYW1lcyAjDQpgYGB7cn0NCmRhdGFfbWFzdGVyX2VkZHk8LXJlYWQuY3N2KHBhc3RlKHBhdGguaW5fZWRkeSwiXFwiLHZlciwiXFwiLGZpbGUubmFtZV9lZGR5LCIuY3N2IixzZXA9IiIpLA0KICAgICAgICAgICAgICAgICAgaGVhZGVyPUYsDQogICAgICAgICAgICAgICAgICBza2lwPTMsDQogICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzPWMoLTk5OTkpLA0KICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYpDQpjb2xuYW1lcyhkYXRhX21hc3Rlcl9lZGR5KTwtY29sbmFtZXMoDQogIHJlYWQuY3N2KHBhc3RlKHBhdGguaW5fZWRkeSwiXFwiLHZlciwiXFwiLGZpbGUubmFtZV9lZGR5LCIuY3N2IixzZXA9IiIpLA0KICAgICAgICAgICBoZWFkZXI9VCwNCiAgICAgICAgICAgc2tpcD0xKSkNCg0KI2RhdGFfbWFzdGVyX2VkZHkNCmBgYA0KDQoNCiMgRGVmaW5pbmcgdGhlIGRhdGEgSS9PIGRpcmVjdG9yeSBmb3IgdGhlIE1hc3RlciBtZXRfZGF0YSAjDQoNCmBgYHtyfQ0KcGF0aF9tZXQ8LSJDOlxcVXNlcnNcXFRvbW15XFxmbHV4XFxEYXRhLWV4cGxvcmluZ1xcMDJfQ29uY29yZFxcIg0KcGF0aC5pbl9tZXQ8LXBhc3RlKHBhdGhfbWV0LCIwMV9Qcm9jY2Vzc2VkX0RhdGEiLHNlcD0iIikNCnBhdGgub3V0X21ldDwtcGFzdGUocGF0aF9tZXQsIjAzX2NvbWJpbmVkX2RhdGEiLHNlcD0iIikNCnZlcjwtIm1ldF9kYXRhIiANCmZpbGUubmFtZTwtcGFzdGUoIk1FVF9kYXRhX21hc3RlciIsc2VwPSIiKQ0KYGBgDQoNCg0KDQoNCiNyZWFkIGluIE1ldF9EYXRhIE1hc3RlciBmaWxlLCBwYXJzZSB2YXJpYWJsZSBuYW1lcyBhbmQgZGVmaW5lIE4vQXMjDQoNCg0KYGBge3J9DQptZXRfZGF0YV9tYXN0ZXI8LXJlYWQuY3N2KHBhc3RlKHBhdGguaW5fbWV0LCJcXCIsdmVyLCJcXCIsZmlsZS5uYW1lLCIuY3N2IixzZXA9IiIpLA0KICAgICAgICAgICAgICAgICAgaGVhZGVyPUYsDQogICAgICAgICAgICAgICAgICBza2lwPTQsDQogICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzPWMoIk5BTiIpLA0KICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYpDQpjb2xuYW1lcyhtZXRfZGF0YV9tYXN0ZXIpPC1jb2xuYW1lcygNCiAgcmVhZC5jc3YocGFzdGUocGF0aC5pbl9tZXQsIlxcIix2ZXIsIlxcIixmaWxlLm5hbWUsIi5jc3YiLHNlcD0iIiksDQogICAgICAgICAgIGhlYWRlcj1ULA0KICAgICAgICAgICBza2lwPSAxKSkNCg0KI21ldF9kYXRhX21hc3Rlcg0KDQpgYGANCg0KDQoNCg0KIyBQYXJzaW5nIHRoZSB0aW1lIHN0YW1wIGNvbnZlcnRpbmcgaXQgaW50byBhIFBPU0lYbHQgdmVjdG9yIw0KDQoqKmludGVycHJldGluZyBkYXRlIGFuZCB0aW1lIGludG8gbmV3IHRpbWVzdGFtcCBjb2x1bW4qKg0KDQoqKlRoZW4gdGFraW5nIHRoYXQgdGltZSBzdGFtcCBjb2x1bW4gYW5kIHR1cm5pbmcgZWFjaCB0aW1lIGludG8gYSB1bmlxdWUgbnVtYmVyICh0aW1lLmlkKSBzbyBJIGNhbiBqb2luIGJhc2VkIG9uIHRoYXQuIEFzIGl0IGNhbiBiZSByZWFsbHkgdHJpY2t5IHRvIGpvaW4vbWVyZ2UgYmFzZWQgb24gdGltZSBzdGFtcHMgYWxvbmUqKg0KDQoqKk9yIEkgY291bGQgbWFrZSBzdXJlIGJvdGggdGltZSBzdGFtcHMgYXJlIGNoYXJhY3RlcnMgYW5kIG1hdGNoIHRoZW0gdGhhdCB3YXkqKg0KDQoqKkZpbmFsbHkgcGxvdGluZyB0aW1lLmlkIHRvIG1ha2Ugc3VyZSBteSB0aW1lcyB0cmFuc2xhdGUgbGluZWFyaWx5KioNCg0KYGBge3J9DQpkYXRhX21hc3Rlcl9lZGR5JFRJTUVTVEFNUDwtc3RycHRpbWUocGFzdGUoZGF0YV9tYXN0ZXJfZWRkeSRkYXRlLGRhdGFfbWFzdGVyX2VkZHkkdGltZSxzZXA9IiAiKSxmb3JtYXQ9IiVtLyVkLyVZICVIOiVNIiwgdHogPSAiR01UIikNCg0KZGF0YV9tYXN0ZXJfZWRkeSR0aW1lLmlkPC1kYXRhX21hc3Rlcl9lZGR5JFRJTUVTVEFNUCR5ZWFyKzE5MDArKGRhdGFfbWFzdGVyX2VkZHkkVElNRVNUQU1QJHlkYXkpLzM2NisoZGF0YV9tYXN0ZXJfZWRkeSRUSU1FU1RBTVAkaG91cikvMzY2LzI0KyAoZGF0YV9tYXN0ZXJfZWRkeSRUSU1FU1RBTVAkbWluKS8zNjYvMjQvNjANCg0KZGF0YV9tYXN0ZXJfZWRkeSR0aW1lLmlkWzE6NTBdDQpwbG90KGRhdGFfbWFzdGVyX2VkZHkkdGltZS5pZCkNCndoaWNoKGR1cGxpY2F0ZWQoZGF0YV9tYXN0ZXJfZWRkeSR0aW1lLmlkKSkNCmBgYA0KDQoNCiNUYWtpbmcgdGhlIG1ldF9kYXRhIGFuZCB0dXJuaW5nIHRoZSB0aW1lIHN0YW1wIGludG8gcG9zaXh0IGZvcm1hdCMNCg0KYGBge3J9DQptZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QPC1zdHJwdGltZShtZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0iJW0vJWQvJVkgJUg6JU0iLCB0eiA9ICJHTVQiKQ0KDQptZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QWzE6MjBdDQpgYGANCg0KI01ha2luZyBzdXJlIHRpbWVzdGFtcCBjb2x1bW5zIGxpbmUgdXAjDQoNCmBgYHtyfQ0KDQptZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QWzE6MTBdDQoNCmRhdGFfbWFzdGVyX2VkZHkkVElNRVNUQU1QWzE6MTBdDQpgYGANCg0KDQpgYGB7cn0NCm1ldF9kYXRhX21hc3Rlcg0KYGBgDQoNCiNjcmVhdGluZyBhIHRpbWUgaWQgZm9yIHRoZSBNRVQgRGF0YSBzbyBJIEkgY2FuIGpvaW4gdGhlIE1FVCBhbmQgRWRkeSBQcm8gRGF0YSMNCg0KYGBge3J9DQoNCm1ldF9kYXRhX21hc3RlciR0aW1lLmlkIDwtbWV0X2RhdGFfbWFzdGVyJFRJTUVTVEFNUCR5ZWFyKzE5MDArKG1ldF9kYXRhX21hc3RlciRUSU1FU1RBTVAkeWRheSkvMzY2KyhtZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QJGhvdXIpLzM2Ni8yNCArIChtZXRfZGF0YV9tYXN0ZXIkVElNRVNUQU1QJG1pbikvMzY2LzI0LzYwIA0KDQptZXRfZGF0YV9tYXN0ZXIkdGltZS5pZFsxOjIwXQ0KcGxvdChtZXRfZGF0YV9tYXN0ZXIkdGltZS5pZCkNCndoaWNoKGR1cGxpY2F0ZWQobWV0X2RhdGFfbWFzdGVyJHRpbWUuaWQpKQ0KDQptZXRfZGF0YV9tYXN0ZXINCmBgYA0KDQoNCiNKb2luaW5nIHRoZSBNZXRfRGF0YSBhbmQgRWRkeSBQcm8gRGF0YSBTZXRzIw0KDQoqKndpdGggbWVyZ2UqKg0KDQpgYGB7cn0NCg0KY29tYm9fbWFzdGVyX2VkX21ldDwtIG1lcmdlKG1ldF9kYXRhX21hc3RlclssLXdoaWNoKGNvbG5hbWVzKG1ldF9kYXRhX21hc3Rlcik9PSJUSU1FU1RBTVAiKV0sIGRhdGFfbWFzdGVyX2VkZHlbLC13aGljaChjb2xuYW1lcyhkYXRhX21hc3Rlcl9lZGR5KT09IlRJTUVTVEFNUCIpXSwgYnkgPSAidGltZS5pZCIpDQoNCmNvbWJvX21hc3Rlcl9lZF9tZXQNCg0KY29sbmFtZXMoY29tYm9fbWFzdGVyX2VkX21ldCkNCg0KYGBgDQoNCg0KI0FkZCBiYWNrIHRpbWUgc3RhbXAgdG8gdGhlIGNvbWJvX21hc3Rlcl9lZF9tZXQjDQpgYGB7cn0NCmNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QPC1zdHJwdGltZShwYXN0ZShjb21ib19tYXN0ZXJfZWRfbWV0JGRhdGUsY29tYm9fbWFzdGVyX2VkX21ldCR0aW1lLHNlcD0iICIpLGZvcm1hdD0iJW0vJWQvJVkgJUg6JU0iLCB0eiA9ICJHTVQiKQ0KDQpjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUFsxOjEwXQ0KDQpjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUFsxMDQ1MToxMDQ1M10NCg0KY29tYm9fbWFzdGVyX2VkX21ldA0KDQoNCg0KYGBgDQoNCiNDcmVhdGluZyBhIENTViBGaWxlIG9mIG15IGNvbWJpbmVkIE1hc3RlciBGaWxlISMNCmBgYHtyfQ0Kd3JpdGUuY3N2KGNvbWJvX21hc3Rlcl9lZF9tZXQsDQogICAgICAgICAgcGFzdGUocGF0aC5vdXRfZWRkeSx2ZXIsImNvbWJvX21hc3Rlcl9lZF9tZXQiLHNlcD0iIiksDQogICAgICAgICAgcXVvdGUgPSBULA0KICAgICAgICAgIHJvdy5uYW1lcyA9IEYpDQpgYGANCg0KI2ZpbHRlcmluZyBkYXRhIGZvciBxdWFsaXR5IGNvbnRyb2wgZmlsdGVycyMNCioqZmlsdGVyaW5nIGxhdGVudCBoZWF0LCBzZW5zaWJsZSBoZWF0LCBjbzIgZmx1eCwgcWNfdGF1IGFuZCBoMjBmbHV4IGJ5IHF1YWxpdHkgY29udHJvbHMqKg0KDQpgYGB7cn0NCmNvbWJvX21hc3Rlcl9lZF9tZXQkTEUuWyFpcy5uYShjb21ib19tYXN0ZXJfZWRfbWV0JHFjX0xFKSZjb21ib19tYXN0ZXJfZWRfbWV0JHFjX0xFPT0yXTwtTkENCg0KY29tYm9fbWFzdGVyX2VkX21ldCRxcWNfaDJvX2ZsdXhbIWlzLm5hKGNvbWJvX21hc3Rlcl9lZF9tZXQkcWNfaDJvX2ZsdXgpJmNvbWJvX21hc3Rlcl9lZF9tZXQkcWNfaDJvX2ZsdXg9PTJdPC1OQQ0KDQpjb21ib19tYXN0ZXJfZWRfbWV0JEhbIWlzLm5hKGNvbWJvX21hc3Rlcl9lZF9tZXQkcWNfSCkmY29tYm9fbWFzdGVyX2VkX21ldCRxY19IPT0yXTwtTkENCg0KY29tYm9fbWFzdGVyX2VkX21ldCR1LlshaXMubmEoY29tYm9fbWFzdGVyX2VkX21ldCRxY19UYXUpJmNvbWJvX21hc3Rlcl9lZF9tZXQkcWNfVGF1PT0yXTwtTkENCg0KY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eFshaXMubmEoY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eCkmY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eD09Ml08LU5BDQoNCg0KYGBgDQoNCiMgbGF0ZW50IGhlYXQsIHNlbnNpYmxlIGhlYXQsIGgyMF9mbHV4LCBhbmQgcmVsYXRpdmUgaHVtaWRpdHkgYnkgZGF5IGZvciB3aG9sZSBwZXJpb2QgIw0KDQoNCmBgYHtyfQ0KDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JExFKQ0KaGlzdChjb21ib19tYXN0ZXJfZWRfbWV0JExFKQ0KDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JGgyb19mbHV4KQ0KDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JEgpDQoNCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkUkgpDQoNCg0KDQoNCg0KDQpgYGANCg0KDQoNCiNIYWxmIEhvdXIgRmx1eCBBdmVyYWdlcw0KDQpgYGB7cn0NCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXgseGxhYj0nVGltZScsIHlsYWI9J0NvMiBGbHV4ZXMnLCBtYWluPScgSGFsZiBIb3VyIENvMiBGbHV4IEF2ZXJhZ2VzJywgIHlsaW0gPSBjKC0yMCwyMCkscGNoPTEsY29sPSJibHVlIixjZXg9MC40KQ0KYGBgDQoNCiNEYWlseSBhdmVyYWdlIG9mIGZsdXhlcyANCmBgYHtyfQ0KDQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JGNvMl9mbHV4ICxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSwgeGxhYj0nVGltZScsIHlsYWI9J0NvMiBGbHV4ZXMnLCBtYWluPSdEYWlseSBDbzIgRmx1eCBBdmVyYWdlcycscGNoPTEsY29sPSJyZWQiLGNleD0xLjUpDQoNCmBgYA0KDQojUGxvdHRpbmcgQ28yIGZsdXggYnkgdGltc3RhbXAgb24geC1heGlzLiBGaXJzdCBoYWxmLWhvdXJseSBkYXRhIGFuZCBkYWlseSBkYXRhIHN0YWNrZWQgDQoNCmBgYHtyfQ0KbGF5b3V0KG1hdHJpeChjKDEsMSwyLDIpLCAyLCAyLCBieXJvdyA9IFRSVUUpKQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eCwgeGxhYj0nVGltZScsIHlsYWI9J0NvMiBGbHV4ZXMnLCBtYWluPSdIYWxmIEhvdXIgRmx1eCBBdmVyYWdlcycsICB5bGltID0gYygtMTUsMTUpLHBjaD0xLGNvbD0iYmx1ZSIsY2V4PTAuNCkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXggLHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSxmdW5jdGlvbih4KSBtZWFuKHgsbmEucm09VCkpLCB4bGFiPSdUaW1lJywgeWxhYj0nQ28yIEZsdXhlcycsIG1haW49J0RhaWx5IENvMiBGbHV4IEF2ZXJhZ2VzJyxwY2g9MSxjb2w9InJlZCIsY2V4PTEuNSkNCg0KDQpgYGANCg0KDQpgYGB7cn0NCg0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eCwNCiAgeWxpbSA9IGMoLTEwLCAxMCksDQogICAgICAgICAgICAgICBjZXg9MC42LGNvbD0iZ3JleSIsDQogICAgICAgICAgICAgICB4bGFiPSAnVGltZScsIA0KICAgICAgICAgICAgICAgeWxhYj0iIiwgDQogICAgICAgICAgICAgICBtYWluPScnLGxhcz0xLA0KICAgICAgICAgICAgICAgbHBhcnM9bGlzdChsd2Q9Myxjb2w9InJlZCIpKQ0KbXRleHQoc2lkZT0yLGV4cHJlc3Npb24oQ09bMl1+Rmx1eH4nKCd+bXV+bW9sfm1eey0yfX5zXnstMX1+JyknKSxsaW5lPTIuNSkNCnBhcihuZXc9IFRSVUUpDQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JGNvMl9mbHV4ICxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSwNCiAgICAgeGF4dD0nbicsIA0KICAgICB4bGFiPSdUaW1lJywgDQogICAgIHlsYWI9JycsIA0KICAgICBtYWluPScnLCBsYXMgPTEsDQogICAgIHlsaW0gPSBjKC0xMCwxMCksDQogICAgIGx0eT0xLGNvbD0icmVkIiwNCiAgICAgbHdkPTIsdHlwZT0ibCIpDQptdGV4dChzaWRlPTIsZXhwcmVzc2lvbihDT1syXX5GbHV4ficoJ35tdX5tb2x+bV57LTJ9fnNeey0xfX4nKScpLGxpbmU9Mi41KQ0KYWJsaW5lKGg9MCxjb2w9ImJsYWNrIikNCg0KYGBgDQoNCg0KI1Bsb3R0aW5nIGRhaWx5IGZsdXggYXZlcmFnZSBvdmVyIGhhbGYgaG91ciBmbHV4ZXMNCmBgYHtyfQ0KDQoNCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXgsIA0KICAgICB4bGFiPSdUaW1lJywgDQogICAgIHlsYWI9J0NvMiBGbHV4ZXMnLCANCiAgICAgbWFpbj0nJywgIHlsaW0gPSBjKC0xMCwxMCkscGNoPTEsY29sPSJncmV5IixjZXg9MC40KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXggLHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSxmdW5jdGlvbih4KSBtZWFuKHgsbmEucm09VCkpLHhheHQ9J24nLCB4bGFiPSdUaW1lJywgeWxhYj0nQ28yIEZsdXhlcycsIG1haW49JycseWxpbSA9IGMoLTEwLDEwKSxsdHk9MSxjb2w9InJlZCIsbHdkPTIsdHlwZT0ibCIpDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KbGVnZW5kKHg9J2JvdHRvbXJpZ2h0JyxsZWdlbmQ9YygnMS8yIGhvdXIgZmx1eGVzJywgJ2RhaWx5IGZsdXggYXZlcmFnZXMnKSwNCmNvbD1jKCdncmV5JywgJ3JlZCcpLCBwY2g9YygxLDE5KSkNCg0KYGBgDQoNCiNEYWlseSBhdmVyYWdlIG9mIFNlbnNpYmxlIEhlYXQgIA0KYGBge3J9DQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JEgscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkseGxhYj0nVGltZScsIHlsYWI9J1NlbnNpYmxlIEhlYXQnLCBtYWluPSdEYWlseSBBdmVyYWdlIG9mIFNlbnNpYmxlIEhlYXQnKQ0KYGBgDQoNCg0KI0RhaWx5IGF2ZXJhZ2Ugb2YgTGF0ZW50IEhlYXQgIA0KYGBge3J9DQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JExFICxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSx4bGFiPSdUaW1lJywgeWxhYj0nTGF0ZW50IEhlYXQnLCBtYWluPSdEYWlseSBBdmVyYWdlIG9mIExhdGVudCBIZWF0JykNCmBgYA0KDQoNCg0KI2xpbmUgcGxvdCBvZiBjMDJfZmx1eGVzIw0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbWJvX21hc3Rlcl9lZF9tZXQpICsgDQogIGdlb21fbGluZShtYXBwaW5nID0gYWVzKHggPSB0aW1lLmlkICwgeSA9IGNvMl9mbHV4KSkgDQoNCmBgYA0KDQoNCiNsYXRlbnQgaGVhdCBhbmQgU2Vuc2libGUgaGVhdCBwbG90dGVkIG92ZXIgZWFjaG90aGVyDQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRMRSwNCiAgICAgeGxhYj0nVGltZScsIA0KICAgICB5bGFiPSdMYXRlbnQgYW5kIFNlbnNpYmxlIEhlYXQnLCANCiAgICAgbWFpbj0nTGF0ZW50IGFuZCBTZW5zaWJsZSBIZWF0JyxwY2g9MSxjb2w9ImJsdWUiLGNleD0wLjYpDQpwb2ludHMoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkSCwNCiAgICAgICBjb2w9InJlZCIsDQogICAgICAgcGNoPTEsDQogICAgICAgY2V4PTAuNikNCmxlZ2VuZCh4PSdib3R0b21yaWdodCcsbGVnZW5kPWMoJ0xhdGVudCBIZWF0JywgJ1NlbnNpYmxlIEhlYXQnKSwNCmNvbD1jKCdibHVlJywgJ3JlZCcpLCBwY2g9YygxLDE5KSkNCg0KYGBgDQoNCiNhaXIgdGVtcGVyYXR1ZSBieSBzZW5zaWJsZSBoZWF0IGFuIFUqIGJ5IGNvMiBmbHV4DQpgYGB7cn0NCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRhaXJfdGVtcGVyYXR1cmUtMjczLjE1LGNvbWJvX21hc3Rlcl9lZF9tZXQkSCx4bGltPWMoMTAsNDApLHlsaW09YygtMTAwLDUwMCkpDQoNCg0KDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkdS4gLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXgsIHlsaW0gPSBjKDAsIDEwKSwgeGxpbSA9IGMoMCwxKSkNCmBgYA0KDQoNCiNBZGRpbmcgYmVzdCBmaXQgbGluZSB0byBhaXIgdGVtcGVyYXR1cmUgYnkgc2Vuc2libGUgaGVhdA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbWJvX21hc3Rlcl9lZF9tZXQpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gYWlyX3RlbXBlcmF0dXJlLTI3My4xNSwgeSA9IEgpKSArDQogIGdlb21fc21vb3RoKG1hcHBpbmcgPSBhZXMoeCA9IGFpcl90ZW1wZXJhdHVyZS0yNzMuMTUsIHkgPSBIKSkNCg0KDQpgYGANCg0KI2Jlc3QgZml0IGxpbmUgdG8gVSogYnQgY28yIGZsdXgNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb21ib19tYXN0ZXJfZWRfbWV0KSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHUuLCB5ID0gY28yX2ZsdXgpKSArDQogIGdlb21fc21vb3RoKG1hcHBpbmcgPSBhZXMoeCA9IHUuLCB5ID0gY28yX2ZsdXgpKQ0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQpoaXN0KGNvbWJvX21hc3Rlcl9lZF9tZXQkd2luZF9kaXIsIHhsaW0gPSBjKDAsMzcwKSwgYnJlYWtzID0gMzYsIG1haW4gPSAiV2luZCBEaXJlY3Rpb24gYXQgQ29uY29yZCBUb3dlciIsIHhsYWIgPSAnRGVncmVlcycpDQpgYGANCg0KI0NvbXBhcmluZyBNRVQgVGVtcGVyYXR1cmUgZGF0YSB0byB0ZW1wZXJhdHVyZSByZWFkaW5nIGZyb20gTGljb3IgaW50cnVtZW50cyMNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRQVGVtcF9DX0F2ZykNCnBvaW50cyhjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCxjb21ib19tYXN0ZXJfZWRfbWV0JGFpcl90ZW1wZXJhdHVyZS0yNzMuMTUsY29sPSJyZWQiLHBjaD0yKQ0KYGBgDQoNCg0KDQojQWRkaW5nIGNvZWZmaWNpZW50IHRvIE5ldCByYWRpYXRpb24jDQpgYGB7cn0NCmNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUiA9IChjb21ib19tYXN0ZXJfZWRfbWV0JE5SX1dtMl9BdmcqMTApLzE0LjINCmBgYA0KDQojcGxvdHRpbmcgYWlyIHRlbXBlcmF0dXJlIGZyb20gZGF0YSBsb2dnZXIuIHNlZSB3aGVyZSBvdXIgZ2FwcyBsaW5lIHVwLiBsaW5lcyB1cCB3aXRoIG5ldCByYWRpYXRpb24gYW5kIGdhcHMNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JEFpclRfQXZnKQ0KYGBgDQoNCiNwbG90dGluZyBOZXQgUmFkYXRpb24gdG8gc2VlIHRoZSBiYWQgZGF0YS4gDQpgYGB7cn0NCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SW2MoMTo2MDAsMjUwMDo0MDAwKV0pDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUikNCmBgYA0KDQoNCiNmaWx0ZXJpbmcgb3V0IGJhZCBOUiBudW1iZXJzDQoNCmBgYHtyfQ0KDQpjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3RfTlJbIWlzLm5hKGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUikmKGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUjwoLTE1MCl8Y29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SPjgwMCldPC1OQQ0Kc3VtbWFyeShjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3RfTlIpDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUikNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SKQ0KYGBgDQoNCg0KI0FkZGluZyBjb2VmZmljaWVudCB0byBTb2lsIEhlYXQgRmx1eCBEYXRhDQpgYGB7cn0NCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRTSEZfMV9tVl9BdmcseWxpbT1jKC0xMCwxMCkpDQpjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEgPSAoY29tYm9fbWFzdGVyX2VkX21ldCRTSEZfMV9tVl9BdmcqMTYuNDU1KQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEseWxpbT1jKC01MCw1MCkpDQpgYGANCg0KI3Bsb3R0aW5nIFNvaWwgaGVhdCBmbHV4IHRvIHNlZSB0aGUgYmFkIGRhdGEuIA0KYGBge3J9DQoNCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X3NoZl8xKQ0KDQpzdW1tYXJ5KGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMVtjKDI1MDA6NDAwMCldKQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEpDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMVtjKDI1MDA6NDAwMCldLCB5bGltID0gYygtNTAsNTApLHhsYWI9JzgvMTQvMjAxOSB0byAwMi8wNS8yMDIwJywgeWxhYj0nU29pbCBIZWF0IEZsdXhfMSAnLCBtYWluPSdIYWxmIEhvdXIgQXZlcmFnZXMgb2YgU29pbCBIZWF0IEZsdXggb2YgdGhlIENvbmNvcmQgU2l0ZScpDQoNCmBgYA0KDQoNCg0KI2ZpbHRlcmluZyBvdXQgYmFkIHNvaWwgaGVhdCBmbHV4IG51bWJlcnMNCg0KYGBge3J9DQoNCmNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMVshaXMubmEoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X3NoZl8xKSYoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X3NoZl8xPCgtMjApfGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMT41MCldPC1OQQ0Kc3VtbWFyeShjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEpDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMSkNCmBgYA0KDQoqKkVuZXJneSBCYWxhbmNlIG9mIG5vbi1nYXBmaWxsZWQgZGF0YS4gU2xvcGUgb2YgbGluZSBpcyBlbmVyZ3kgYmFsYW5jZSBjbG9zdXJlLiBJZGVhbGx5IGl0IHNob3VsZCBiZSAxOjEgTmV0IHJhZGlhdGlvbiAtIHNvaWwgaGVhdCBmbHV4PSB0byBMYXRlbnQgaGVhdCArc2Vuc2libGUgaGVhdC4gKioNCg0KYGBge3J9DQoNCg0KY29tYm9fbWFzdGVyX2VkX21ldCRFX25nID0gKGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9OUi1jb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEpDQoNCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRFX25nICkNCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRFX25nKQ0KDQpjb21ib19tYXN0ZXJfZWRfbWV0JEVfbGVfYW5kX0ggPShjb21ib19tYXN0ZXJfZWRfbWV0JExFK2NvbWJvX21hc3Rlcl9lZF9tZXQkSCkNCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRFX2xlX2FuZF9IICApDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkRV9sZV9hbmRfSCApDQoNCnNjYXR0ZXIuc21vb3RoKGNvbWJvX21hc3Rlcl9lZF9tZXQkRV9uZywgY29tYm9fbWFzdGVyX2VkX21ldCRFX2xlX2FuZF9IICkNCmxtKGNvbWJvX21hc3Rlcl9lZF9tZXQkRV9sZV9hbmRfSCAgfiBjb21ib19tYXN0ZXJfZWRfbWV0JEVfbmcpDQpzdW1tYXJ5KGxtKGNvbWJvX21hc3Rlcl9lZF9tZXQkRV9sZV9hbmRfSCAgfiBjb21ib19tYXN0ZXJfZWRfbWV0JEVfbmctMSkpDQpgYGANCg0KDQoNCiMxLzIgaG91ciBhbmQgZGFpbHkgYXZlcmFnZXMgb2YgTGF0ZW50IEhlYXQNCg0KDQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRMRSwgDQogICAgIHhsYWI9J1RpbWUnLCANCiAgICAgeWxhYj0gZXhwcmVzc2lvbihMYXRlbnR+SGVhdH4nKCd+V35tXnstMn1+JyknKSwgDQogICAgIG1haW49JycsICANCiAgICAgeWxpbSA9IGMoLTQwLDMwMCksDQogICAgIHBjaD0xLA0KICAgICBjb2w9ImdyZXkiLGNleD0wLjQpDQpwYXIobmV3PSBUUlVFKQ0KcGxvdCh0YXBwbHkoY29tYm9fbWFzdGVyX2VkX21ldCRMRSAscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSksDQogICAgIHhheHQ9J24nLCANCiAgICAgeGxhYj0nVGltZScsIA0KICAgIHlsYWI9IGV4cHJlc3Npb24oTGF0ZW50fkhlYXR+Jygnfld+bV57LTJ9ficpJyksICANCiAgICAgbWFpbj0nJywNCiAgICAgeWxpbSA9IGMoLTQwLDMwMCksbHR5PTEsY29sPSJyZWQiLGx3ZD0yLHR5cGU9ImwiKQ0KYWJsaW5lKGg9MCxjb2w9ImJsYWNrIikNCmBgYA0KDQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRMRSwNCiAgeWxpbSA9IGMoLTQwLCAzMDApLA0KICAgICAgICAgICAgICAgY2V4PTAuNCxjb2w9ImdyZXkiLA0KICAgICAgICAgICAgICAgeGxhYj0gJ1RpbWUnLCANCiAgICAgICAgICAgICAgIHlsYWI9IiIsIA0KICAgICAgICAgICAgICAgbWFpbj0nJyxsYXM9MSwNCiAgICAgICAgICAgICAgIGxwYXJzPWxpc3QobHdkPTMsY29sPSJyZWQiKSkNCm10ZXh0KHNpZGU9MixleHByZXNzaW9uKExhdGVudH5IZWF0ficoJ35Xfm1eey0yfX4nKScpLGxpbmU9Mi41KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkTEUgLHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSxmdW5jdGlvbih4KSBtZWFuKHgsbmEucm09VCkpLA0KICAgICB4YXh0PSduJywgDQogICAgIHhsYWI9J1RpbWUnLCANCiAgICAgeWxhYj0nJywgDQogICAgIG1haW49JycsIGxhcyA9MSwNCiAgICAgeWxpbSA9IGMoLTQwLDMwMCksDQogICAgIGNvbD0icmVkIixwY2g9MSxjZXg9MS4wKQ0KbXRleHQoc2lkZT0yLGV4cHJlc3Npb24oTGF0ZW50fkhlYXR+Jygnfld+bV57LTJ9ficpJyksbGluZT0yLjUpDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KbGVnZW5kKHg9J3RvcHJpZ2h0JyxsZWdlbmQ9YygnMS8yIGhvdXIgYXZlcmFnZXMnLCAnZGFpbHkgYXZlcmFnZXMnKSwNCmNvbD1jKCdncmV5JywgJ3JlZCcpLCBwY2g9YygxOSwxKSkNCmBgYA0KDQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRMRSwgDQogICAgIHhsYWI9J1RpbWUnLCANCiAgICAgeWxhYj0nTGF0ZW50IEhlYXQnLCANCiAgICAgbWFpbj0nTGF0ZW50IEhlYXQ6IERhaWx5IGFuZCBIYWxmIEhvdXIgQXZlcmFnZXMnLCANCiAgICAgeWxpbSA9IGMoLTQwLDMwMCkscGNoPTEsY29sPSJncmV5IixjZXg9MC40KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkTEUgLHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSxmdW5jdGlvbih4KSBtZWFuKHgsbmEucm09VCkpLHhheHQ9J24nDQogICAgICwgeGxhYj0nVGltZScsDQogICAgIHlsYWI9J0xhdGVudCBIZWF0JywgDQogICAgIG1haW49J0xhdGVudCBIZWF0OiBEYWlseSBhbmQgSGFsZiBIb3VyIEF2ZXJhZ2VzJywNCiAgICAgeWxpbSA9IGMoLTQwLDMwMCksDQogICAgIGNvbD0icmVkIixwY2g9MSxjZXg9MS4wKQ0KYWJsaW5lKGg9MCxjb2w9ImJsYWNrIikNCmxlZ2VuZCh4PSd0b3ByaWdodCcsbGVnZW5kPWMoJzEvMiBob3VyIGF2ZXJhZ2VzJywgJ2RhaWx5IGF2ZXJhZ2VzJyksDQpjb2w9YygnZ3JleScsICdyZWQnKSwgcGNoPWMoMSwxKSkNCmBgYA0KDQoNCg0KIzEvMiBob3VyIGFuZCBkYWlseSBhdmVyYWdlcyBvZiBTZW5zaWJsZSBIZWF0DQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRILCB4bGFiPSdUaW1lJywgeWxhYj0nU2Vuc2libGUgSGVhdCcsIG1haW49J1NlbnNpYmxlIEhlYXQ6IERhaWx5IGFuZCBIYWxmIEhvdXIgQXZlcmFnZXMnLCAgeWxpbSA9IGMoLTQwLDMwMCkscGNoPTEsY29sPSJncmV5IixjZXg9MC40KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkSCAscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkseGF4dD0nbicsIHhsYWI9J1RpbWUnLCB5bGFiPSdTZW5zaWJsZSBIZWF0JywgbWFpbj0nU2Vuc2libGUgSGVhdDogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycseWxpbSA9IGMoLTQwLDMwMCksbHR5PTEsY29sPSJyZWQiLGx3ZD0yLHR5cGU9ImwiKQ0KYWJsaW5lKGg9MCxjb2w9ImJsYWNrIikNCmBgYA0KDQoNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRILCB4bGFiPSdUaW1lJywgeWxhYj0nU2Vuc2libGUgSGVhdCcsIG1haW49J1NlbnNpYmxlIEhlYXQ6IERhaWx5IGFuZCBIYWxmIEhvdXIgQXZlcmFnZXMnLCAgeWxpbSA9IGMoLTQwLDMwMCkscGNoPTEsY29sPSJncmV5IixjZXg9MC40KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkSCAscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkseGF4dD0nbicsIHhsYWI9J1RpbWUnLCB5bGFiPSdTZW5zaWJsZSBIZWF0JywgbWFpbj0nU2Vuc2libGUgSGVhdDogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycseWxpbSA9IGMoLTQwLDMwMCksY29sPSJyZWQiLHBjaD0xLGNleD0xLjApDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KYGBgDQoNCg0KYGBge3J9DQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JEgsDQogIHlsaW0gPSBjKC00MCwgMzAwKSwNCiAgICAgICAgICAgICAgIGNleD0wLjQsY29sPSJncmV5IiwNCiAgICAgICAgICAgICAgIHhsYWI9ICdUaW1lJywgDQogICAgICAgICAgICAgICB5bGFiPSIiLCANCiAgICAgICAgICAgICAgIG1haW49JycsbGFzPTEsDQogICAgICAgICAgICAgICBscGFycz1saXN0KGx3ZD0zLGNvbD0icmVkIikpDQptdGV4dChzaWRlPTIsZXhwcmVzc2lvbihTZW5zaWJsZX5IZWF0ficoJ35Xfm1eey0yfX4nKScpLGxpbmU9Mi41KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkSCAscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSksDQogICAgIHhheHQ9J24nLCANCiAgICAgeGxhYj0nVGltZScsIA0KICAgICB5bGFiPScnLCANCiAgICAgbWFpbj0nJywgbGFzID0xLA0KICAgICB5bGltID0gYygtNDAsMzAwKSwNCiAgICAgY29sPSJyZWQiLHBjaD0xLGNleD0xLjApDQptdGV4dChzaWRlPTIsZXhwcmVzc2lvbihTZW5zaWJsZX5IZWF0ficoJ35Xfm1eey0yfX4nKScpLGxpbmU9Mi41KQ0KYWJsaW5lKGg9MCxjb2w9ImJsYWNrIikNCmBgYA0KDQojTmV0IFJhZGlhdGlvbiBEYWlseSBhbmQgMS8yIGhvdXIgYXZlcmFnZXMNCg0KYGBge3J9DQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3RfTlIsIHhsYWI9J1RpbWUnLCB5bGFiPSdOZXQgUmFkaWF0aW9uJywgbWFpbj0nTmV0IFJhZGlhdGlvbjogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsICB5bGltID0gYygtODAsODAwKSxwY2g9MSxjb2w9ImdyZXkiLGNleD0wLjQpDQpwYXIobmV3PSBUUlVFKQ0KcGxvdCh0YXBwbHkoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SICxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSx4YXh0PSduJywgeGxhYj0nVGltZScsIHlsYWI9J05ldCBSYWRpYXRpb24nLCBtYWluPSdOZXQgUmFkaWF0aW9uOiBEYWlseSBhbmQgSGFsZiBIb3VyIEF2ZXJhZ2VzJyx5bGltID0gYygtODAsODAwKSxsdHk9MSxjb2w9InJlZCIsbHdkPTIsdHlwZT0ibCIpDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KYGBgDQoNCmBgYHtyfQ0KDQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3RfTlIsIHhsYWI9J1RpbWUnLCB5bGFiPSdOZXQgUmFkaWF0aW9uJywgbWFpbj0nTmV0IFJhZGlhdGlvbjogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsICB5bGltID0gYygtODAsODAwKSxwY2g9MSxjb2w9ImdyZXkiLGNleD0wLjQpDQpwYXIobmV3PSBUUlVFKQ0KcGxvdCh0YXBwbHkoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SICxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSx4YXh0PSduJywgeGxhYj0nVGltZScsIHlsYWI9J05ldCBSYWRpYXRpb24nLCBtYWluPSdOZXQgUmFkaWF0aW9uOiBEYWlseSBhbmQgSGFsZiBIb3VyIEF2ZXJhZ2VzJyx5bGltID0gYygtODAsODAwKSxjb2w9InJlZCIscGNoPTEsY2V4PTEuMCkNCmFibGluZShoPTAsY29sPSJibGFjayIpDQoNCmBgYA0KDQoNCiNzb2lsIGhlYXQgZmx1eA0KYGBge3J9DQpwbG90KGNvbWJvX21hc3Rlcl9lZF9tZXQkVElNRVNUQU1QICxjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEsIHhsYWI9J1RpbWUnLCB5bGFiPSdTb2lsIEhlYXQgRmx1eCAxJywgbWFpbj0nU29pbCBIZWF0IEZsdXggMTogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsICB5bGltID0gYygtMjAsNDApLHBjaD0xLGNvbD0iZ3JleSIsY2V4PTAuNCkNCnBhcihuZXc9IFRSVUUpDQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkseGF4dD0nbicsIHhsYWI9J1RpbWUnLCB5bGFiPSdTb2lsIEhlYXQgRmx1eCAxJywgbWFpbj0nU29pbCBIZWF0IEZsdXggMTogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycseWxpbSA9IGMoLTIwLDQwKSxsdHk9MSxjb2w9InJlZCIsbHdkPTIsdHlwZT0ibCIpDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkQ29ycmVjdF9zaGZfMSwgeGxhYj0nVGltZScsIHlsYWI9J1NvaWwgSGVhdCBGbHV4JywgbWFpbj0nU29pbCBIZWF0IEZsdXggMTogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsICB5bGltID0gYygtMjAsNDApLHBjaD0xLGNvbD0iZ3JleSIsY2V4PTAuNCkNCnBhcihuZXc9IFRSVUUpDQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3Rfc2hmXzEscm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkseGF4dD0nbicsIHhsYWI9J1RpbWUnLCB5bGFiPSdTb2lsIEhlYXQgRmx1eCAxJywgbWFpbj0nU29pbCBIZWF0IEZsdXggMTogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycseWxpbSA9IGMoLTIwLDQwKSxjb2w9InJlZCIscGNoPTEsY2V4PTEuMCkNCmFibGluZShoPTAsY29sPSJibGFjayIpDQpgYGANCg0KI2FpciB0ZW1wZXJhdHVyZSBkYWlseSBhbmQgMS8yIGhvdXIgYXZlcmFnZXMNCmBgYHtyfQ0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JFRJTUVTVEFNUCAsY29tYm9fbWFzdGVyX2VkX21ldCRhaXJfdGVtcGVyYXR1cmUtMjczLjE1LCB4bGFiPSdUaW1lJywgeWxhYj0nQWlyIFRlbXBlcmF0dXJlIEM6IERhaWx5IGFuZCAxLzIgSG91ciBBdmVyYWdlcycsIG1haW49JyAnLCAgeWxpbSA9IGMoNSw0MCkscGNoPTEsY29sPSJncmV5IixjZXg9MC40KQ0KcGFyKG5ldz0gVFJVRSkNCnBsb3QodGFwcGx5KGNvbWJvX21hc3Rlcl9lZF9tZXQkYWlyX3RlbXBlcmF0dXJlLTI3My4xNSxyb3VuZChjb21ib19tYXN0ZXJfZWRfbWV0JERPWSksZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSx4YXh0PSduJywgeGxhYj0nVGltZScsIHlsYWI9J0FpciBUZW1wZXJhdHVyZSBDOiBEYWlseSBhbmQgMS8yIEhvdXIgQXZlcmFnZXMnLCBtYWluPScnLHlsaW0gPSBjKDUsNDApLGx0eT0xLGNvbD0icmVkIixsd2Q9Mix0eXBlPSJsIikNCmFibGluZShoPTAsY29sPSJibGFjayIpDQpgYGANCg0KDQojV2F0ZXIgRmx1eGVzIGRhaWx5IGFuZCAxLzIgaG91ciBhdmVyYWdlcy4gY3VtdWxhdGl2ZSB3YXRlciBhbmQgY28yDQpgYGB7cn0NCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRUSU1FU1RBTVAgLGNvbWJvX21hc3Rlcl9lZF9tZXQkaDJvX2ZsdXgsIHhsYWI9J1RpbWUnLCB5bGFiPSdIMk8gRmx1eGVzJywgbWFpbj0nSDJPIEZsdXhlczogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsICB5bGltID0gYygtMiw1KSxwY2g9MSxjb2w9ImdyZXkiLGNleD0wLjQpDQpwYXIobmV3PSBUUlVFKQ0KDQpwbG90KHRhcHBseShjb21ib19tYXN0ZXJfZWRfbWV0JGgyb19mbHV4LA0KICAgICAgICAgICAgcm91bmQoY29tYm9fbWFzdGVyX2VkX21ldCRET1kpLA0KICAgICAgICAgICAgZnVuY3Rpb24oeCkgbWVhbih4LG5hLnJtPVQpKSwNCiAgICAgeGF4dD0nbicsDQogICAgIHhsYWI9J1RpbWUnLA0KICAgICB5bGFiPSdIMk8gRmx1eGVzJywNCiAgICAgbWFpbj0nSDJPIEZsdXhlczogRGFpbHkgYW5kIEhhbGYgSG91ciBBdmVyYWdlcycsDQogICAgIHlsaW0gPSBjKC0yLDUpLA0KICAgICBsdHk9MSwNCiAgICAgY29sPSJyZWQiLA0KICAgICBsd2Q9MiwNCiAgICAgdHlwZT0ibCIpDQphYmxpbmUoaD0wLGNvbD0iYmxhY2siKQ0KDQpwbG90KGN1bXN1bSh0YXBwbHkoY29tYm9fbWFzdGVyX2VkX21ldCRoMm9fZmx1eCwNCiAgICAgICAgICAgIHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSwNCiAgICAgICAgICAgIGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkpKjE4LjAyLzEwMDAwMDAqMTgwMCo0OCwNCiAgICAgeGF4dD0nbicsDQogICAgIHhsYWI9J0RheXMgc2luY2UgSnVuZSAyNScsDQogICAgIHlsYWI9ZXhwcmVzc2lvbihDdW11bGF0aXZlfkV2YXBvdHJhbnNwaXJhdGlvbn4nKCd+bW1+JyknKSwNCiAgICAgbWFpbj0nJywNCiAgICAgeWxpbSA9IGMoMCwyNDApLA0KICAgICBsdHk9MSwNCiAgICAgY29sPSJyZWQiLA0KICAgICBsd2Q9MiwNCiAgICAgdHlwZT0ibCIpDQpheGlzKHNpZGU9MSxhdD1zZXEoMCwyNDAsYnk9MzApKQ0KDQpwbG90KGN1bXN1bSh0YXBwbHkoY29tYm9fbWFzdGVyX2VkX21ldCRjbzJfZmx1eCwNCiAgICAgICAgICAgIHJvdW5kKGNvbWJvX21hc3Rlcl9lZF9tZXQkRE9ZKSwNCiAgICAgICAgICAgIGZ1bmN0aW9uKHgpIG1lYW4oeCxuYS5ybT1UKSkpKjEyLzEwMDAwMDAqMTgwMCo0OCwNCiAgICAgeGF4dD0nbicsDQogICAgIHhsYWI9J0RheXMgc2luY2UgSnVuZSAyNScsDQogICAgIHlsYWI9ZXhwcmVzc2lvbihDdW11bGF0aXZlfk5FRX4nKCd+Z35Dfm1eey0yfX4nKScpLA0KICAgICBtYWluPScnLA0KICAgICB5bGltID0gYygtMTAwLDEwMCksDQogICAgIGx0eT0xLA0KICAgICBjb2w9InJlZCIsDQogICAgIGx3ZD0yLA0KICAgICB0eXBlPSJsIikNCmF4aXMoc2lkZT0xLGF0PXNlcSgwLDI0MCxieT0zMCkpDQoNCmBgYA0KDQojQ28yIGZsdXhlcyB2LnMgdSBzdGFyLCB0ZW1wZXJhdHVyZSwgYW5kIFZQRA0KDQpgYGB7cn0NCg0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JHUuICxjb21ib19tYXN0ZXJfZWRfbWV0JGNvMl9mbHV4LCB5bGltID0gYygtNSwgMTApLCB4bGltID0gYygwLDEpLCB4bGFiPSdVKicsIHlsYWI9J0NvMiBGbHV4ZXMnLCBtYWluPSdDbzIgRmx1eGVzIHYucyBVKicpDQoNCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRWUEQgLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXgsIHlsaW0gPSBjKC01LCAxMCksIHhsYWI9J1ZQRCcsIHlsYWI9J0NvMiBGbHV4ZXMnLCBtYWluPSdDbzIgRmx1eGVzIHYucyBWUEQqJykNCg0KcGxvdChjb21ib19tYXN0ZXJfZWRfbWV0JGFpcl90ZW1wZXJhdHVyZS0yNzMuMTUgLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXgsIHlsaW0gPSBjKC01LCAxMCksIHhsYWI9J0FpciBUZW1wZXJhdHVyZSAoQyknLCB5bGFiPSdDbzIgRmx1eGVzJywgbWFpbj0nQ28yIEZsdXhlcyB2LnMgQWlyIHRlbXBlcmF0dXJlKicpDQoNCnBsb3QoY29tYm9fbWFzdGVyX2VkX21ldCRDb3JyZWN0X05SW2NvbWJvX21hc3Rlcl9lZF9tZXQkZGF5dGltZT09MV0gLGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXhbY29tYm9fbWFzdGVyX2VkX21ldCRkYXl0aW1lPT0xXSwgeWxpbSA9IGMoLTEwLCAxMCksIHhsYWI9J05ldCBSYWRpYXRpb24nLCB5bGFiPSdDbzIgRmx1eGVzJywgbWFpbj0nQ28yIEZsdXhlcyB2LnMgTmV0IFJhZGlhdGlvbicpDQoNCnN1bW1hcnkoY29tYm9fbWFzdGVyX2VkX21ldCRWUEQpDQpzY2F0dGVyLnNtb290aChjb21ib19tYXN0ZXJfZWRfbWV0JENvcnJlY3RfTlJbY29tYm9fbWFzdGVyX2VkX21ldCRkYXl0aW1lPT0xXSwNCiAgICAgICAgICAgICAgIGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXhbY29tYm9fbWFzdGVyX2VkX21ldCRkYXl0aW1lPT0xXSwNCiAgICAgICAgICAgICAgIHlsaW0gPSBjKC0xMCwgMTApLA0KICAgICAgICAgICAgICAgY2V4PTAuNixjb2w9ImdyZXkiLA0KICAgICAgICAgICAgICAgeGxhYj1leHByZXNzaW9uKERheXRpbWV+TmV0flJhZGlhdGlvbn4nKCd+V35tXnstMn1+JyknKSwgDQogICAgICAgICAgICAgICB5bGFiPSIiLCANCiAgICAgICAgICAgICAgIG1haW49JycsbGFzPTEsDQogICAgICAgICAgICAgICBscGFycz1saXN0KGx3ZD0zLGNvbD0icmVkIikpDQptdGV4dChzaWRlPTIsZXhwcmVzc2lvbihDT1syXX5GbHV4ficoJ35tdX5tb2x+bV57LTJ9fnNeey0xfX4nKScpLGxpbmU9Mi41KQ0KDQpzY2F0dGVyLnNtb290aChjb21ib19tYXN0ZXJfZWRfbWV0JGFpcl90ZW1wZXJhdHVyZVtjb21ib19tYXN0ZXJfZWRfbWV0JGRheXRpbWU9PTAmDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbWJvX21hc3Rlcl9lZF9tZXQkdS4+PTAuMTVdLTI3My4xNSwNCiAgICAgICAgICAgICAgIGNvbWJvX21hc3Rlcl9lZF9tZXQkY28yX2ZsdXhbY29tYm9fbWFzdGVyX2VkX21ldCRkYXl0aW1lPT0wJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21ib19tYXN0ZXJfZWRfbWV0JHUuPj0wLjE1XSwNCiAgICAgICAgICAgICAgIHlsaW0gPSBjKC01LCAxMCksDQogICAgICAgICAgICAgICBjZXg9MC42LGNvbD0iZ3JleSIsDQogICAgICAgICAgICAgICB4bGFiPWV4cHJlc3Npb24oQWlyflRlbXBlcmF0dXJlficoJ35kZWdyZWV+Q34nKScpLCANCiAgICAgICAgICAgICAgIHlsYWI9IiIsIA0KICAgICAgICAgICAgICAgbWFpbj0nJyxsYXM9MSwNCiAgICAgICAgICAgICAgIGxwYXJzPWxpc3QobHdkPTMsY29sPSJyZWQiKSkNCm10ZXh0KHNpZGU9MixleHByZXNzaW9uKENPWzJdfkZsdXh+Jygnfm11fm1vbH5tXnstMn1+c157LTF9ficpJyksbGluZT0yLjUpDQoNCmBgYA0KDQojY3VtdWxhdGl2ZSANCg==